﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

using System.Data.SqlServerCe;
using System.Windows.Forms;

namespace ICRprojekt.Baza
{
    public static class BazaCentar
    {
        private static string StrVeza = "";
        private static SqlCeConnection ConVeza;
        private static bool inicijalizirano;

        /// <summary>
        /// #DINO
        /// Inicijalizacija veze s bazom.
        /// </summary>
        public static void Pocetak()
        {
            StrVeza = "Data Source=" + System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + @"\Baza\baza.sdf;Persist Security Info=False;";
            ConVeza = new SqlCeConnection(StrVeza);
            ConVeza.Open();
            inicijalizirano = true;
        }

        /// <summary>
        /// #DINO
        /// Zatvaranje veze s bazom.
        /// Pozvati pri zatvaranju programa. (trigger)
        /// Radi i bez da se zatvara.
        /// </summary>
        public static void Kraj()
        {
            inicijalizirano = false;
            ConVeza.Close();
        }

        /// <summary>     
        /// #DINO
        /// Testiranje rada s bodovima.
        /// Unosi 3 rezultata i nakon toga ispiše najviša 3.
        /// Pozivanjem se ne brišu stari podaci.
        /// </summary>
        public static void Test_Bodovi()
        {
            Pocetak();
            Bodovi_Insert(new HighScoreItem("Filip", 500));
            Bodovi_Insert(new HighScoreItem("Dodo", 200));
            Bodovi_Insert(new HighScoreItem("Klemen", 100));
            List<HighScoreItem> bodovi = Bodovi_Select(3);
            foreach (HighScoreItem element in bodovi)
            {
                MessageBox.Show(element.Name + " " + element.Score.ToString());
            }
            Kraj();
        }

        /// <summary>     
        /// #DINO
        /// Testiranje rada s pitanjima.
        /// Unosi sva pitanja u bazu koja se predaju kao parametar.
        /// Nakon toga ih sve ispiše.
        /// Ako se pozove više puta, stvaraju se duplikati.
        /// </summary>
        /// <param name="pitanjaIzTxt">Lista pitanja dohvaćenih iz txt datoteke</param>
        public static void Test_Pitanja(List<Pitanje> pitanjaIzTxt)
        {
            Pocetak();
            foreach (Pitanje pitanje in pitanjaIzTxt)
            {
                Pitanja_Insert(pitanje);
            }
            List<Pitanje> pitanjaIzBaze = Pitanja_Select();
            foreach (Pitanje pitanje in pitanjaIzBaze)
            {
                if (pitanje.Kategorija != KategorijaPitanja.Jackpot) MessageBox.Show(pitanje.TestIspis1());
                else MessageBox.Show(pitanje.TestIspis2());
            }
            Kraj();
        }

        /// <summary>     
        /// #DINO
        /// Unosi highscore u bazu.
        /// </summary>
        /// <param name="bodovi">Struktura koja se umeće u bazu.</param>
        public static void Bodovi_Insert(HighScoreItem bodovi)
        {
            try
            {
                int idx = Max_ID("Bodovi") + 1;
                using (SqlCeCommand com = new SqlCeCommand("INSERT INTO Bodovi(ID, Ime, Rezultat) VALUES(@id,@ime,@rez)", ConVeza))
                {
                    com.Parameters.AddWithValue("@id", idx);
                    com.Parameters.AddWithValue("@ime", bodovi.Name);
                    com.Parameters.AddWithValue("@rez", bodovi.Score);
                    com.ExecuteNonQuery();
                }
            }
            catch
            {
                throw new Exception("Greška pri umetanju u bazu.");
            }
        }

        /// <summary>     
        /// #DINO
        /// Dohvaća listu highscorea iz baze.
        /// </summary>
        /// <param name="topMjesta">Koliko najboljih rezultata treba ispisati.</param>
        /// <returns>Lista HighScore-a</returns>
        public static List<HighScoreItem> Bodovi_Select(int topMjesta)
        {
            int brojac = 0;
            List<HighScoreItem> povratnaLista = new List<HighScoreItem>();
            try
            {
                if (inicijalizirano == false) BazaCentar.Pocetak();
                using (SqlCeCommand com = new SqlCeCommand("SELECT * FROM Bodovi ORDER BY Rezultat DESC", ConVeza))
                {
                    SqlCeDataReader reader = com.ExecuteReader();
                    while (reader.Read())
                    {
                        brojac++;
                        string ime = reader.GetString(1);
                        int rezultat = reader.GetInt32(2);
                        HighScoreItem noviBodovi = new HighScoreItem(ime, rezultat);
                        povratnaLista.Add(noviBodovi);
                        if (brojac >= topMjesta) break;
                    }
                }
            }
            catch
            {
                throw new Exception("Greška pri dohvatu iz baze.");
            }
            return povratnaLista;
        }

        /// <summary>     
        /// #DINO
        /// Unosi pitanje u bazu. Paziti na duplikate.
        /// </summary>
        /// <param name="pitanje">Pitanje koje se umeće u bazu.</param>
        public static void Pitanja_Insert(Pitanje pitanje)
        {
            try
            {
                int idx = Max_ID("Pitanja") + 1;
                using (SqlCeCommand com = new SqlCeCommand("INSERT INTO Pitanja VALUES(@id,@kat,@pit_1,@odg_1A,@odg_1B,@odg_1C,@odg_1,@pit_2,@odg_2)", ConVeza))
                {
                    com.Parameters.AddWithValue("@id", idx);
                    com.Parameters.AddWithValue("@kat", UcitavanjePitanja.DohvatIzDatoteke.OdrediKraticu(pitanje.Kategorija));
                    if (pitanje.Kategorija != KategorijaPitanja.Jackpot)
                    {
                        com.Parameters.AddWithValue("@pit_1", pitanje.PrvoPitanje);
                        com.Parameters.AddWithValue("@odg_1A", pitanje.PrvoOdgovori[0]);
                        com.Parameters.AddWithValue("@odg_1B", pitanje.PrvoOdgovori[1]);
                        com.Parameters.AddWithValue("@odg_1C", pitanje.PrvoOdgovori[2]);
                        com.Parameters.AddWithValue("@odg_1", pitanje.PrvoTocan);
                    }
                    else
                    {
                        com.Parameters.AddWithValue("@pit_1", "");
                        com.Parameters.AddWithValue("@odg_1A", "");
                        com.Parameters.AddWithValue("@odg_1B", "");
                        com.Parameters.AddWithValue("@odg_1C", "");
                        com.Parameters.AddWithValue("@odg_1", "");
                    }
                    com.Parameters.AddWithValue("@pit_2", pitanje.DrugoPitanje);
                    com.Parameters.AddWithValue("@odg_2", pitanje.DrugoOdgovor);
                    com.ExecuteNonQuery();
                }
            }
            catch
            {
                throw new Exception("Greška pri umetanju u bazu.");
            }
        }

        /// <summary>     
        /// #DINO
        /// Dohvaća listu svih pitanja iz baze.
        /// </summary>
        /// <returns>pitanja</returns>
        public static List<Pitanje> Pitanja_Select()
        {
            List<Pitanje> povratnaLista = new List<Pitanje>();
            try
            {
                if (inicijalizirano == false) BazaCentar.Pocetak();
                using (SqlCeCommand com = new SqlCeCommand("SELECT * FROM Pitanja", ConVeza))
                {
                    SqlCeDataReader reader = com.ExecuteReader();
                    while (reader.Read())
                    {
                        int idx = reader.GetInt32(0);
                        KategorijaPitanja kat = UcitavanjePitanja.DohvatIzDatoteke.OdrediKategoriju(reader.GetString(1));
                        string pit_1 = "";
                        string odg_1 = "";
                        List<String> odgL_1 = new List<string>();
                        if (kat != KategorijaPitanja.Jackpot)
                        {
                            pit_1 = reader.GetString(2);
                            odgL_1.Add(reader.GetString(3));
                            odgL_1.Add(reader.GetString(4));
                            odgL_1.Add(reader.GetString(5));
                            odg_1 = reader.GetString(6);
                        }
                        else
                        {
                            pit_1 = "";
                            odg_1 = "";
                        }
                        string pit_2 = reader.GetString(7);
                        string odg_2 = reader.GetString(8);
                        Pitanje novoPitanje = new Pitanje(kat, idx, pit_1, odgL_1, odg_1, pit_2, odg_2);
                        povratnaLista.Add(novoPitanje);
                    }
                }
            }
            catch
            {
                throw new Exception("Greška pri dohvatu iz baze.");
            }
            return povratnaLista;
        }

        /// <summary>     
        /// #DINO
        /// Traži najveći ID u bazi da bi se mogao izračunati novi jedinstveni ID.
        /// Dakle, ne koristi se ID koji se pročita u txt datoteci, nego on sam povećava broj.
        /// Lako se promijeni ako treba.
        /// </summary>
        /// <param name="tablica">Ime tablice u kojoj se traži maximalni ID (Bodovi ili Pitanja)</param>
        /// <returns>Najveći ID koji postoji u bazi</returns>
        private static int Max_ID(string tablica)
        {
            int povratnaVrijednost = 0;
            try
            {
                if (inicijalizirano == false) BazaCentar.Pocetak();
                using (SqlCeCommand com = new SqlCeCommand("SELECT MAX(ID) FROM " + tablica, ConVeza))
                {
                    SqlCeDataReader reader = com.ExecuteReader();
                    while (reader.Read())
                    {
                        if (reader.IsDBNull(0)) return 0;
                        povratnaVrijednost = reader.GetInt32(0);
                    }
                }
            }
            catch
            {
                throw new Exception("Greška pri dohvatu iz baze.");
            }
            return povratnaVrijednost;
        }

    }
}
